//=============================================================================
// Fallout Grenade.
//=============================================================================
class TFNKFalloutGren extends TFProjectile;

var float ExpStart;
var bool exploded, bHitWater;
var xEmitter Trail, Smoketrail, chargeSparks;
var class<xEmitter> HitEffectClass;
var float LastSparkTime;
var int myteam;

var() vector ShakeRotMag;           // how far to rot view
var() vector ShakeRotRate;          // how fast to rot view
var() float  ShakeRotTime;          // how much time to rot the instigator's view
var() vector ShakeOffsetMag;        // max view offset vertically
var() vector ShakeOffsetRate;       // how fast to offset view vertically
var() float  ShakeOffsetTime;       // how much time to offset view

replication
{
    reliable if (Role==ROLE_Authority)
        myteam, ExpStart, smoketrail, exploded;
}

simulated function Destroyed()
{
    if ( Trail != None )
        Trail.mRegen = false;
	if ( SmokeTrail != None )
        SmokeTrail.mRegen = false;
    Super.Destroyed();
}

simulated function PostBeginPlay()
{
    Super.PostBeginPlay();

    if ( Level.NetMode != NM_DedicatedServer)
    {
        Trail = Spawn(class'TaskForces.TFNKTrail', self,, Location, Rotation);
        trail.SetBase(self);
    }

    if ( Role == ROLE_Authority )
    {
        Velocity = Speed * Vector(Rotation);
        RandSpin(10000);
        if (Instigator.HeadVolume.bWaterVolume)
        {
            bHitWater = true;
            Velocity = 0.6*Velocity;
        }
    }

    settimer(0.1, false);
}

simulated function Timer()
{
    if(smoketrail==none && Level.NetMode != NM_DedicatedServer)
    {
        if(myteam==0) SmokeTrail = Spawn(class'TaskForces.TFNKSmoketrailR', self,, Location, Rotation);
        else SmokeTrail = Spawn(class'TaskForces.TFNKSmoketrailB', self,, Location, Rotation);
        smoketrail.SetBase(self);
    }
}

function Landed( vector HitNormal )
{
    BlowUp(Location);
}

simulated function ProcessTouch( actor Other, vector HitLocation )
{
    if(other!=instigator) BlowUp(Location);
}

function HitWall( vector HitNormal, actor Wall )
{
    Explode(Location, HitNormal);
}

simulated function Explode(vector HitLocation, vector HitNormal)
{
	bFixedRotationDir=false;
    SetRotation(Rotator(hitnormal));

    if ( Trail != None )
        Trail.mRegen = false;
	if ( SmokeTrail != None )
        SmokeTrail.mRegen = false;
    if (Trail != None )
        Trail.Destroy();
	if (SmokeTrail != None )
		SmokeTrail.Destroy();

    BlowUp(HitLocation);
}

function BlowUp(vector HitLocation)
{
    if(exploded) return;
    exploded=true;

    if ( Role == ROLE_Authority )
		MakeNoise(1.0);

    Spawn(class'Taskforces.TFNKExp',,, HitLocation);
    Spawn(class'Taskforces.TFNKRadSparks',,, HitLocation);
    Spawn(class'Taskforces.TFNKFallout',,, HitLocation);
    DmgRadius(vect(100,90,0), 1, 0.20, 300, 800, class'Taskforces.DamTypeNKRad', MomentumTransfer, HitLocation);

    GotoState('Radiation');
}

final function DmgRadius(vector flash, float dmgPctHard, float dmgPctThru, float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
	local actor Victims;
	local float damageScale, dist;
	local vector dir;

	if( bHurtEntry )
		return;

    if(instigator==none)
	{
	    if(pawn(owner)!=none)
            instigator=pawn(owner);
	    else if(instigatorcontroller!=none && instigatorcontroller.pawn!=none)
	        instigator=instigatorcontroller.pawn;
	    else if(controller(owner)!=none && controller(owner).pawn!=none)
	        instigator=controller(owner).pawn;
	}

	bHurtEntry = true;
	foreach CollidingActors( class 'Actor', Victims, DamageRadius, HitLocation )
	{
		// don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
		if( victims!=none && (Victims != self) && (Victims.Role == ROLE_Authority) && (!Victims.IsA('FluidSurfaceInfo')) )
		{
			dir = Victims.Location - HitLocation;
			dist = FMax(1,VSize(dir));
			dir = dir/dist;
			damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);

            if(!fasttrace(Victims.Location, hitlocation)) damagescale*=dmgPctThru;

            if(pawn(victims)!=none) damagescale=damagescale;
            else damagescale*=dmgPctHard;

            if(damage>0)
            {
                Victims.TakeDamage
			    (
				    damageScale * DamageAmount,
				    Instigator,
				    Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
				    (damageScale * Momentum * dir),
				    DamageType
			    );

			    if(pawn(victims)!=none && pawn(victims).controller!=none && playercontroller(pawn(victims).controller)!=none && flash!=vect(0,0,0))
                    playercontroller(pawn(victims).controller).clientflash(0.1, flash*damagescale);
		    }
        }
	}
	bHurtEntry = false;
}

state Radiation
{
	function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation,
							Vector momentum, class<DamageType> damageType) {}

    function BeginState()
    {
        bHidden = true;
		SetPhysics(PHYS_None);
		SetCollision(false,false,false);

        bDynamicLight=true;

        ShakeView();

		InitialState = 'Radiation';
        if ( Trail != None )
            Trail.mRegen = false;
	    if ( SmokeTrail != None )
            SmokeTrail.mRegen = false;
        if (Trail != None )
			Trail.Destroy();
		if (SmokeTrail != None )
			SmokeTrail.Destroy();

        settimer(0.1, true);
    }

    simulated function timer()
    {
        local int i;
        local rotator rot;
        local vector vec;
        local float x;

        if(expstart==0)
        {
            expstart=level.TimeSeconds;

            for(i=0; i<7; i++)
            {
                rot=rotation;
                rot.Pitch+=29000*frand()-14500;
                rot.Yaw+=29000*frand()-14500;
                rot.Roll+=29000*frand()-14500;

                Vec=Location+vector(rot)*(rand(200)+200);

                DmgRadius(vect(100,90,0), 1, 0.20, 150, 500, class'Taskforces.DamTypeNKShock', MomentumTransfer, Vec);
                Spawn(class'Taskforces.TFNKExp',,, Vec,Rot);
                Spawn(class'Taskforces.TFNKFalloutExp',,, Vec,Rot);
            }
        }

        if(level.TimeSeconds<expstart+45)
        {
            x=(level.TimeSeconds-expstart)/45;

            DmgRadius(vect(200,600,0), 0.01, 0.9, Damage*(1-x), DamageRadius+DamageRadius*x, class'Taskforces.DamTypeNKRad', MomentumTransfer*0, Location);
            lightbrightness=fmax(0,255-(x*255));
        }
        else destroy();
    }

    function ShakeView()
    {
        local Controller C;
        local PlayerController PC;
        local float Dist, Scale;

        for ( C=Level.ControllerList; C!=None; C=C.NextController )
        {
            PC = PlayerController(C);
            if ( PC != None && PC.ViewTarget != None )
            {
                Dist = VSize(Location - PC.ViewTarget.Location);
                if ( Dist < DamageRadius * 2.0)
                {
                    if (Dist < DamageRadius)
                        Scale = 1.0;
                    else
                        Scale = (DamageRadius*2.0 - Dist) / (DamageRadius);
                    C.ShakeView(ShakeRotMag*Scale, ShakeRotRate, ShakeRotTime, ShakeOffsetMag*Scale, ShakeOffsetRate, ShakeOffsetTime);
                }
            }
        }
    }

Begin:

    PlaySound(sound'TFMedia.TFNKRadExp',SLOT_None,4*TransientSoundVolume);
}

defaultproperties
{
     HitEffectClass=Class'XEffects.WallSparks'
     ShakeRotMag=(Z=100.000000)
     ShakeRotRate=(Z=1000.000000)
     ShakeRotTime=4.000000
     ShakeOffsetMag=(Z=5.000000)
     ShakeOffsetRate=(Z=100.000000)
     ShakeOffsetTime=6.000000
     Speed=1750.000000
     MaxSpeed=2500.000000
     TossZ=0.000000
     Damage=75.000000
     DamageRadius=1000.000000
     MomentumTransfer=50000.000000
     MyDamageType=Class'taskforces.DamTypeNKRad'
     ImpactSound=Sound'TFMedia.Nuke.TFNKRadExp'
     ExplosionDecal=Class'XEffects.RocketMark'
     LightType=LT_Steady
     LightEffect=LE_QuadraticNonIncidence
     LightHue=54
     LightSaturation=128
     LightRadius=64.000000
     DrawType=DT_StaticMesh
     StaticMesh=StaticMesh'XGame_rc.BallMesh'
     bNetTemporary=False
     Physics=PHYS_Falling
     LifeSpan=999.000000
     DrawScale=1.500000
     AmbientGlow=100
     TransientSoundVolume=1.000000
     TransientSoundRadius=2000.000000
     CollisionRadius=4.000000
     CollisionHeight=4.000000
     bFixedRotationDir=True
     DesiredRotation=(Pitch=12000,Yaw=5666,Roll=2334)
}
